﻿using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design.WebControls;

namespace MyLib.Web.UI {
	/// <summary>
	/// 
	/// </summary>
	[ParseChildren(false)]
	[PersistChildren(true)]
	[DefaultProperty("Title")]
	[Designer(typeof(MyPanelContainerDesigner))]
	[ToolboxData("<{0}:MyPanel runat=\"server\"></{0}:MyPanel>")]
	public class MyPanel : System.Web.UI.WebControls.WebControl {
		#region Private fields
		private Style m_titleBarStyle;

		private Style m_titleStyle;

		private Style m_contentStyle;
		#endregion

		/// <summary>
		/// 
		/// </summary>
		[Bindable(true)]
		[Category("Accessibility")]
		[DefaultValue("")]
		public string Title {
			get {
				var obj = ViewState["Title"];
				if (obj == null) {
					return "";
				} else {
					return (string)obj;
				}
			}
			set {
				ViewState["Title"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("MyPanel_TitleBarStyle"),
		NotifyParentProperty(true),
		Category("Styles"), DefaultValue((string)null),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
		PersistenceMode(PersistenceMode.InnerProperty)]
		public Style TitleBarStyle {
			get {
				if (this.m_titleBarStyle == null) {
					this.m_titleBarStyle = new Style();
					if (base.IsTrackingViewState) {
						((IStateManager)this.m_titleBarStyle).TrackViewState();
					}
				}
				return this.m_titleBarStyle;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("MyPanel_TitleStyle"),
		NotifyParentProperty(true),
		Category("Styles"), DefaultValue((string)null),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
		PersistenceMode(PersistenceMode.InnerProperty)]
		public Style TitleStyle {
			get {
				if (this.m_titleStyle == null) {
					this.m_titleStyle = new Style();
					if (base.IsTrackingViewState) {
						((IStateManager)this.m_titleStyle).TrackViewState();
					}
				}
				return this.m_titleStyle;
			}
		}


		/// <summary>
		/// 
		/// </summary>
		[Description("MyPanel_ContentStyle"),
		NotifyParentProperty(true),
		Category("Styles"), DefaultValue((string)null),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
		PersistenceMode(PersistenceMode.InnerProperty)]
		public virtual Style ContentStyle {
			get {
				if (this.m_contentStyle == null) {
					this.m_contentStyle = new Style();
					if (base.IsTrackingViewState) {
						((IStateManager)this.m_contentStyle).TrackViewState();
					}
				}
				return this.m_contentStyle;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public MyPanel()
			: base(HtmlTextWriterTag.Div) {
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="writer"></param>
		public override void RenderBeginTag(HtmlTextWriter writer) {
			AddAttributesToRender(writer);

			if (!string.IsNullOrWhiteSpace(Title)) {
				writer.RenderBeginTag(HtmlTextWriterTag.Div); // Outter frame.

				TitleBarStyle.AddAttributesToRender(writer);
				writer.RenderBeginTag(HtmlTextWriterTag.Div); // Title bar.

				TitleStyle.AddAttributesToRender(writer);
				writer.RenderBeginTag(HtmlTextWriterTag.Div); // Title.
				writer.WriteEncodedText(Title);
				writer.RenderEndTag();

				writer.RenderEndTag();

				ContentStyle.AddAttributesToRender(writer);
				writer.RenderBeginTag(HtmlTextWriterTag.Div); // Content.
			} else {
				ContentStyle.AddAttributesToRender(writer);
				writer.RenderBeginTag(HtmlTextWriterTag.Div);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="writer"></param>
		public override void RenderEndTag(HtmlTextWriter writer) {
			if (!string.IsNullOrWhiteSpace(Title)) {
				writer.RenderEndTag();
				writer.RenderEndTag();
			} else {
				writer.RenderEndTag();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="writer"></param>
		protected override void AddAttributesToRender(HtmlTextWriter writer) {
			base.AddAttributesToRender(writer);
			string backImageUrl = this.BackImageUrl;
			if (backImageUrl.Trim().Length > 0) {
				writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "url(" + base.ResolveClientUrl(backImageUrl) + ")");
			}
			this.AddScrollingAttribute(this.ScrollBars, writer);
			HorizontalAlign horizontalAlign = this.HorizontalAlign;
			if (horizontalAlign != HorizontalAlign.NotSet) {
				TypeConverter converter = TypeDescriptor.GetConverter(typeof(HorizontalAlign));
				writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, converter.ConvertToInvariantString(horizontalAlign).ToLowerInvariant());
			}
			if (this.Direction == ContentDirection.LeftToRight) {
				writer.AddAttribute(HtmlTextWriterAttribute.Dir, "ltr");
			} else if (this.Direction == ContentDirection.RightToLeft) {
				writer.AddAttribute(HtmlTextWriterAttribute.Dir, "rtl");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="scrollBars"></param>
		/// <param name="writer"></param>
		private void AddScrollingAttribute(ScrollBars scrollBars, HtmlTextWriter writer) {
			switch (scrollBars) {
				case ScrollBars.Horizontal:
					writer.AddStyleAttribute(HtmlTextWriterStyle.OverflowX, "scroll");
					return;
				case ScrollBars.Vertical:
					writer.AddStyleAttribute(HtmlTextWriterStyle.OverflowY, "scroll");
					return;
				case ScrollBars.Both:
					writer.AddStyleAttribute(HtmlTextWriterStyle.Overflow, "scroll");
					return;
				case ScrollBars.Auto:
					writer.AddStyleAttribute(HtmlTextWriterStyle.Overflow, "auto");
					return;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="stateBag"></param>
		public void CopyValuesToViewState(StateBag stateBag) {
			var queue = new System.Collections.Generic.Queue<Control>();

			foreach (Control child in this.Controls) {
				queue.Enqueue(child);
			}

			while (queue.Count != 0) {
				var control = queue.Dequeue();

				if (control is MyTextLine) {
					stateBag[control.ID] = ((MyTextLine)control).Value;
				} else if (control is MyTextBox) {
					stateBag[control.ID] = ((MyTextBox)control).Value;
				} else if(control is MyDropDownList) {
					stateBag[control.ID] = ((MyDropDownList)control).SelectedValue;
				} else if(control is MyCheckBox) {
					stateBag[control.ID] = ((MyCheckBox)control).Checked;
				} else if(control is MyCheckBoxList) {
					stateBag[control.ID] = ((MyCheckBoxList)control).SelectedValue;
				} else if(control is TextBox) {
					stateBag[control.ID] = ((TextBox)control).Text;
				} else if(control is DropDownList) {
					stateBag[control.ID] = ((DropDownList)control).SelectedValue;
				} else if(control is CheckBox) {
					stateBag[control.ID] = ((CheckBox)control).Checked;
				} else if(control is INamingContainer) {
					// Skip all INamingContainer(s).
					continue;
				} else {
					foreach (Control child in control.Controls) {
						queue.Enqueue(child);
					}
				}
			}
		} // end of CopyValuesToViewState.

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected override Style CreateControlStyle() {
			return new PanelStyle(this.ViewState);
		} // endof CreateControlStyle.

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance"), Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(UITypeEditor)), UrlProperty, DefaultValue("")]
		public virtual string BackImageUrl {
			get {
				if (base.ControlStyleCreated) {
					PanelStyle controlStyle = base.ControlStyle as PanelStyle;
					if (controlStyle != null) {
						return controlStyle.BackImageUrl;
					}
					string str = (string)this.ViewState["BackImageUrl"];
					if (str != null) {
						return str;
					}
				}
				return string.Empty;
			}
			set {
				PanelStyle controlStyle = base.ControlStyle as PanelStyle;
				if (controlStyle != null) {
					controlStyle.BackImageUrl = value;
				} else {
					this.ViewState["BackImageUrl"] = value;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[DefaultValue(0), Category("Layout")]
		public virtual ContentDirection Direction {
			get {
				if (base.ControlStyleCreated) {
					PanelStyle controlStyle = base.ControlStyle as PanelStyle;
					if (controlStyle != null) {
						return controlStyle.Direction;
					}
					object obj2 = this.ViewState["Direction"];
					if (obj2 != null) {
						return (ContentDirection)obj2;
					}
				}
				return ContentDirection.NotSet;
			}
			set {
				PanelStyle controlStyle = base.ControlStyle as PanelStyle;
				if (controlStyle != null) {
					controlStyle.Direction = value;
				} else {
					this.ViewState["Direction"] = value;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[DefaultValue(0), Category("Layout")]
		public virtual HorizontalAlign HorizontalAlign {
			get {
				if (base.ControlStyleCreated) {
					PanelStyle controlStyle = base.ControlStyle as PanelStyle;
					if (controlStyle != null) {
						return controlStyle.HorizontalAlign;
					}
					object obj2 = this.ViewState["HorizontalAlign"];
					if (obj2 != null) {
						return (HorizontalAlign)obj2;
					}
				}
				return HorizontalAlign.NotSet;
			}
			set {
				PanelStyle controlStyle = base.ControlStyle as PanelStyle;
				if (controlStyle != null) {
					controlStyle.HorizontalAlign = value;
				} else {
					if ((value < HorizontalAlign.NotSet) || (value > HorizontalAlign.Justify)) {
						throw new ArgumentOutOfRangeException("value");
					}
					this.ViewState["HorizontalAlign"] = value;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Layout"), DefaultValue(0)]
		public virtual ScrollBars ScrollBars {
			get {
				if (base.ControlStyleCreated) {
					PanelStyle controlStyle = base.ControlStyle as PanelStyle;
					if (controlStyle != null) {
						return controlStyle.ScrollBars;
					}
					object obj2 = this.ViewState["ScrollBars"];
					if (obj2 != null) {
						return (ScrollBars)obj2;
					}
				}
				return ScrollBars.None;
			}
			set {
				PanelStyle controlStyle = base.ControlStyle as PanelStyle;
				if (controlStyle != null) {
					controlStyle.ScrollBars = value;
				} else {
					this.ViewState["ScrollBars"] = value;
				}
			}
		}

	} // end of MyPanel.
}
